<template>
  <el-cascader
    :options="options"
    @active-item-change="activeItemChange"
    @change="change"
    :change-on-select="changeOnSelect"
    v-model="productSelect"
    :props="props"
    @focus="init"
    :placeholder="placeholder"
    :disabled="disabled"
  ></el-cascader>
</template>
<script>
import {mapActions} from 'vuex'
import {dotData, copy, isEqual} from '@/utils'
import Emitter from '@/utils/emitter.js'

export default {
  mixins: [Emitter],
  name: 'productSelect',
  componentName: 'productSelect',
  props: {
    value: {
      type: Array,
      default() {
        return []
      }
    },
    changeOnSelect: {
      type: Boolean,
      default: false
    },
    maxLevel: {
      type: Number,
      default: 2
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      options: [],
      optionsMap: new Map(),
      props: {
        label: 'text',
        value: 'value',
        children: '_children'
      },
      productSelect: [],
      isInit: false
    }
  },
  watch: {
    value(val, oldVal) {
      if (isEqual(val, oldVal)) {
        return
      }
      if (val.hasOwnProperty('noRefresh') && val.noRefresh) {
        return
      }
      // 如果值清空了 内部的值也要清空， 防止多级length 不正确
      this.productSelect = []
      this.isInit = true
      this.changeOptionsAndProductSelect()
    }
  },
  created() {
    if (Array.isArray(this.value) && this.value.length) {
      this.init()
    }
  },
  methods: {
    // 初始化获取数据
    init() {
      if (this.isInit) {
        return
      }
      this.changeOptionsAndProductSelect()
      // 获取初始的options
      this.isInit = true
    },
    // 获取options 如果有value就默认选中
    changeOptionsAndProductSelect() {
      this.getProductType().then(arr => {
        if (Array.isArray(arr)) {
          this.options = this.getOptions(arr, this.maxLevel >= 2)
          if (Array.isArray(this.value) && this.value.length) {
            let initValue = copy(this.value, true)
            let code = initValue.shift()
            for (let option of this.options) {
              if (option.code === code) {
                let productSelect = [option]
                this.setInitProductSelect(code, initValue, productSelect)
              }
            }
          }
        }
      })
    },
    // 设置默认的值 2 级到以下的
    setInitProductSelect(parentCode, value, productSelect, level = 1) {
      if (Array.isArray(value) && value.length) {
        let code = value.shift()
        return this.getProductType(parentCode).then(arr => {
          if (Array.isArray(arr) && arr.length) {
            arr = this.getOptions(arr, level <= this.mapGetters)
            this.$set(productSelect[productSelect.length - 1], '_children', arr)
            for (let option of arr) {
              if (option.code === code) {
                return option
              }
            }
          }
        }).then(option => {
          if (option) {
            productSelect.push(option)
          }
          this.setInitProductSelect(code, value, productSelect, level++)
        })
      } else {
        this.productSelect = productSelect
      }
      return Promise.resolve(true)
    },
    // 修改一下后端数据满足
    getOptions(options, hasChildren = true) {
      if (Array.isArray(options)) {
        options.forEach(v => {
          v.code = v.code || v.value
          if (hasChildren) {
            v._children = []
          }
          v.value = v
        })
      }
      return options
    },
    change(data) {
      if (this.changeOnSelect) {
        // todo data 各父级选项组成的数组
      } else {
        // data 是当前值
        this.emitValue(data)
      }
    },
    // 发送值
    emitValue(data) {
      let value = []
      if (Array.isArray(data)) {
        data.forEach(v => {
          value.push(dotData(v, 'code'))
        })
      }
      value.noRefresh = true
      this.$emit('input', value)
      this.$nextTick(_ => {
        this.dispatch('ElFormItem', 'el.form.change', value)
      })
    },
    // 选中变化
    activeItemChange(data) {
      let length = data.length
      let lastOption = dotData(data, length - 1)
      // 设置 _children
      let code = dotData(lastOption, 'code')
      return this.getProductType(code).then(options => {
        // todo 获取到等级
        options = this.getOptions(options, length + 1 < this.maxLevel)
        this.$set(lastOption, '_children', options)
      })
    },
    ...mapActions([
      'getProductType'
    ])
  }
}
</script>
